package com.yingxin.yxerp.module.admin.userdetails;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.yingxin.yx.framework.commons.constant.CommonConst;
import com.yingxin.yx.framework.commons.dto.AttachmentDto;
import com.yingxin.yx.framework.commons.enums.BusinessType;
import com.yingxin.yx.framework.redis.queue.RedisQueueSupport;
import com.yingxin.yx.framework.security.user.PrincipalDto;
import com.yingxin.yx.framework.security.userdetails.WexinUserDetailsService;
import com.yingxin.yx.framework.user.dto.PermissionDto;
import com.yingxin.yx.framework.user.dto.UserDto;
import com.yingxin.yx.framework.web.req.RequestInfo;
import com.yingxin.yx.framework.wx.WeixinAccessToken;
import com.yingxin.yx.framework.wx.WeixinSupport;
import com.yingxin.yxerp.module.attachment.constant.AttachConst;
import com.yingxin.yxerp.module.attachment.service.IAttachmentService;
import com.yingxin.yxerp.module.organization.entity.User;
import com.yingxin.yxerp.module.organization.entity.enums.AccountStatus;
import com.yingxin.yxerp.module.organization.entity.enums.StaffStatus;
import com.yingxin.yxerp.module.organization.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author fanchao
 */
@Slf4j
@Service
public class WeixinUserDetailsServiceImpl implements WexinUserDetailsService {

    @Autowired
    private IUserService userService;

    @Autowired
    private RedisQueueSupport redisQueueSupport;

    @Autowired
    private IAttachmentService attachmentService;

    @Autowired
    private WeixinSupport weixinSupport;

    @Override
    public UserDetails loadUserByUsername(String code) throws AuthenticationException {

        // getAccessToken
        WeixinAccessToken weixinAccessToken = weixinSupport.getAccessToken(code, null);
        if (weixinAccessToken == null) {
            throw new UsernameNotFoundException("用户错误");
        }
        // loginByOpenId
        User user = userService.getByWechatOpenId(weixinAccessToken.getOpenId());

        if (user == null) {
            throw new UsernameNotFoundException("用户错误");
        }
        if (AccountStatus.DISABLED.equals(user.getAccountStatus())) {
            throw new DisabledException("账户被禁用");
        }
        if (AccountStatus.APPLICATION.equals(user.getAccountStatus())) {
            throw new DisabledException("账户被禁用");
        }
        if (StaffStatus.LZ.equals(user.getStaffStatus())) {
            throw new DisabledException("账户被禁用");
        }
        if (CommonConst.TRUE.equals(user.getLockFlag())) {
            throw new DisabledException("账户被锁定，请联系管理员");
        }

        PrincipalDto principal = new PrincipalDto();
        BeanUtil.copyProperties(user, principal);
        principal.setUserId(user.getId());
        // 获取权限
        List<PermissionDto> permissions = permissions(user.getId());
        principal.addResourceSet(permissions);
        principal.buildAuthorities();
        if (!CommonConst.TRUE.equals(principal.getFindByIdFlag())) {
            if (permissions.size() == 0) {
                throw new DisabledException("账户权限不足");
            }
        }

        // 头像
        AttachmentDto avatarDto = attachmentService.getByBiz(user.getId(), BusinessType.USER, AttachConst.AVATAR);
        if (ObjectUtil.isNotEmpty(avatarDto)) {
            principal.setAvatar(avatarDto.getAttachmentPath());
        }

        return principal;
    }

    @Override
    public List<PermissionDto> permissions(String userId) throws AuthenticationException {
        List<PermissionDto> permissions = userService.listPermissionDtoByUserId(userId);
        return permissions;
    }

    @Override
    public void loginSuccessLog(UserDto user, RequestInfo requestInfo) {
    }

    @Override
    public UserDto getUserInfo(String id) {
        User user = userService.getById(id);
        UserDto userDto = new UserDto();
        BeanUtils.copyProperties(user,userDto);
        return userDto;
    }

    /**
     * 记录用户登录错误
     */
    @Override
    public void saveLoginErrorLog(String userName, String password, String loginIp, String pcOrApp){

    }

}
